package com.niiwoo.civet.trade.service.local.newRefund.notify.dubbo;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

import com.niiwoo.civet.trade.service.local.refund.CommonLocalService;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.civet.trade.dao.entity.Project;
import com.niiwoo.civet.trade.dto.ProjectBorrowerAmountSumDTO;
import com.niiwoo.civet.trade.dto.ProjectBorrowerPlanNewDTO;
import com.niiwoo.civet.trade.enums.ProjectPlanStatusEnum;
import com.niiwoo.civet.trade.service.local.newRefund.common.RefundCommonService;
import com.niiwoo.civet.trade.service.local.newRefund.notify.RefundNotifyHandle;
import com.niiwoo.civet.trade.service.local.newRefund.notify.dto.RefundNotifyDTO;
import com.niiwoo.civet.trade.service.local.newRefund.notify.dto.RefundNotifyHandleResult;
import com.niiwoo.civet.trade.service.local.newRefund.notify.enums.RefundNotifyEnum;
import com.niiwoo.civet.trade.utils.RepaymentUtil;
import com.niiwoo.tripod.tiancheng.component.TianChengRefundEventService;
import com.niiwoo.tripod.tiancheng.request.df.ProjectRefundEventRequest;
import com.niiwoo.tripod.tiancheng.request.df.ProjectRefundEventRequestDetail;
import com.niiwoo.tripod.tiancheng.response.common.TianchengUapResponse;

import lombok.extern.slf4j.Slf4j;

/**
 * 天称-借款人还款数据回流 
 *
 * 触发条件：还款
 * 
 * @author: kevin.jia
 * @version 1.0.0
 */
@Slf4j
@Service
public class TianChengBorrowerRefundNotify implements RefundNotifyHandle {

	@Autowired
	private RefundCommonService refundCommonService;
	
	@Autowired
	private TianChengRefundEventService tianChengRefundEventService;

	@Autowired
	private CommonLocalService commonLocalService;

	@Override
	public RefundNotifyHandleResult handle(RefundNotifyDTO refundNotifyDTO) {
		RefundNotifyHandleResult refundNotifyHandleResult = null;
		try {
			ProjectRefundEventRequest projectRefundEventRequest = (ProjectRefundEventRequest) bulidParam(refundNotifyDTO);
			
			log.info("天称-借款人还款数据回流 ，ProjectId：{}， 请求参数：{}", refundNotifyDTO.getProject().getProjectId(), JSONObject.toJSONString(projectRefundEventRequest));
			CompletableFuture<TianchengUapResponse> completableFuture = tianChengRefundEventService.refundSucceed(projectRefundEventRequest);
			TianchengUapResponse tianchengUapResponse = completableFuture.get(3, TimeUnit.SECONDS);
			log.info("天称-借款人还款数据回流 ，ProjectId：{}， 返回结果：{}", refundNotifyDTO.getProject().getProjectId(), JSONObject.toJSONString(tianchengUapResponse));
			refundNotifyHandleResult = new RefundNotifyHandleResult();
		} catch (Exception e) {
			refundNotifyHandleResult = new RefundNotifyHandleResult(e.getMessage());
			log.error("天称-借款人还款数据回流异常，异常原因：{}， 请求参数：{}", e.getMessage(), JSONObject.toJSONString(refundNotifyDTO.getRefundNotifyRecord()), e);
		}
		return refundNotifyHandleResult;
	}
	
	@Override
	public Object bulidParam(RefundNotifyDTO refundNotifyDTO) {
		Project project = refundNotifyDTO.getProject();
		
		// 查询标的还款计划
		List<ProjectBorrowerPlanNewDTO> projectBorrowerPlanNewDTOList = refundCommonService
				.getProjectBorrowerPlanNewList(project.getProjectId(), project.getBorrowUserId());
		
		List<ProjectRefundEventRequestDetail> projectRefundEventRequestDetailList = Lists.newArrayList();
		
		ProjectBorrowerAmountSumDTO projectBorrowerAmountSumDTO = new ProjectBorrowerAmountSumDTO();
		
		// 遍历还款计划生成详情数据，同时累加标的相关金额信息
		projectBorrowerPlanNewDTOList.forEach(projectBorrowerPlanNewDTO -> {
			ProjectRefundEventRequestDetail projectRefundEventRequestDetail = new ProjectRefundEventRequestDetail();
			projectRefundEventRequestDetail.setProjectId(projectBorrowerPlanNewDTO.getProjectId());
			projectRefundEventRequestDetail.setUserId(projectBorrowerPlanNewDTO.getUserId());
			projectRefundEventRequestDetail.setCurrentPeriods(projectBorrowerPlanNewDTO.getPeriod());
			projectRefundEventRequestDetail.setTotalPeriods(projectBorrowerPlanNewDTO.getTotalPeriod());
			projectRefundEventRequestDetail.setRealCostAmount(projectBorrowerPlanNewDTO.getRefundedCapital());
			projectRefundEventRequestDetail.setRealRefundInterest(projectBorrowerPlanNewDTO.getRefundedInterest());
			projectRefundEventRequestDetail.setOverdueFine(projectBorrowerPlanNewDTO.getPenaltyFee());
			projectRefundEventRequestDetail.setStatus(ProjectPlanStatusEnum.enumOf(projectBorrowerPlanNewDTO.getStatus()).getTianchengStatus());
			projectRefundEventRequestDetail.setUpdateTime(projectBorrowerPlanNewDTO.getUpdateTime().getTime()  * 1000L);

			// 结清时间
			if(!Byte.valueOf("1").equals(projectBorrowerPlanNewDTO.getStatus())) {
				if (projectBorrowerPlanNewDTO.getOverDate() != null) {
					projectRefundEventRequestDetail.setRealRefundDate(projectBorrowerPlanNewDTO.getOverDate().getTime() * 1000L);
				} else {
					projectRefundEventRequestDetail.setRealRefundDate(projectBorrowerPlanNewDTO.getRefundDate().getTime() * 1000L);
				}
			}

			Date refundDate = commonLocalService.getCurrentDate();
			if(!Byte.valueOf("1").equals(projectBorrowerPlanNewDTO.getStatus())){
				if (projectBorrowerPlanNewDTO.getOverDate() != null) {
					refundDate = projectBorrowerPlanNewDTO.getOverDate();
				} else {
					refundDate = projectBorrowerPlanNewDTO.getRefundDate();
				}
			}
			
			// 逾期时间
			int overDueDay = RepaymentUtil.getOverdueDay(projectBorrowerPlanNewDTO.getRefundDate(), refundDate);
			if (overDueDay > 0) {
				projectRefundEventRequestDetail.setOverdueDay(overDueDay);
				// 逾期金额 = 待还本金
				projectRefundEventRequestDetail.setOverdueAmount(projectBorrowerPlanNewDTO.getCapital().subtract(projectBorrowerPlanNewDTO.getRefundedCapital()));
			}			
			projectRefundEventRequestDetailList.add(projectRefundEventRequestDetail);
			
			// 累加金额信息
			projectBorrowerAmountSumDTO.setBorrowedAmount(projectBorrowerAmountSumDTO.getBorrowedAmount().add(projectBorrowerPlanNewDTO.getCapital()));
			projectBorrowerAmountSumDTO.setInterest(projectBorrowerAmountSumDTO.getInterest().add(projectBorrowerPlanNewDTO.getInterest()));
			projectBorrowerAmountSumDTO.setManagementFee(projectBorrowerAmountSumDTO.getManagementFee().add(projectBorrowerPlanNewDTO.getManagementFee()));
			projectBorrowerAmountSumDTO.setGuaranteeFee(projectBorrowerAmountSumDTO.getGuaranteeFee().add(projectBorrowerPlanNewDTO.getGuaranteeFee()));
			projectBorrowerAmountSumDTO.setPenaltyFee(projectBorrowerAmountSumDTO.getPenaltyFee().add(projectBorrowerPlanNewDTO.getPenaltyFee()));
			
			projectBorrowerAmountSumDTO.setRefundedCapital(projectBorrowerAmountSumDTO.getRefundedCapital().add(projectBorrowerPlanNewDTO.getRefundedCapital()));
			projectBorrowerAmountSumDTO.setRefundedInterest(projectBorrowerAmountSumDTO.getRefundedInterest().add(projectBorrowerPlanNewDTO.getRefundedInterest()));
			projectBorrowerAmountSumDTO.setRefundedManagementFee(projectBorrowerAmountSumDTO.getRefundedManagementFee().add(projectBorrowerPlanNewDTO.getRefundedManagementFee()));
			projectBorrowerAmountSumDTO.setRefundedGuaranteeFee(projectBorrowerAmountSumDTO.getRefundedGuaranteeFee().add(projectBorrowerPlanNewDTO.getRefundedGuaranteeFee()));
			projectBorrowerAmountSumDTO.setRefundedPenaltyFee(projectBorrowerAmountSumDTO.getRefundedPenaltyFee().add(projectBorrowerPlanNewDTO.getRefundedPenaltyFee()));
		});
		
		// 还款总金额
		BigDecimal totalAmount = projectBorrowerAmountSumDTO.getBorrowedAmount().add(projectBorrowerAmountSumDTO.getInterest())
				.add(projectBorrowerAmountSumDTO.getManagementFee()).add(projectBorrowerAmountSumDTO.getGuaranteeFee())
				.add(projectBorrowerAmountSumDTO.getPenaltyFee());
		
		// 已还款金额
		BigDecimal doneAmount = projectBorrowerAmountSumDTO.getRefundedCapital().add(projectBorrowerAmountSumDTO.getRefundedInterest())
				.add(projectBorrowerAmountSumDTO.getRefundedManagementFee()).add(projectBorrowerAmountSumDTO.getRefundedGuaranteeFee())
				.add(projectBorrowerAmountSumDTO.getRefundedPenaltyFee());
		
		// 剩余应还金额 = 还款总金额 - 已还金额
		BigDecimal lateAmount = totalAmount.subtract(doneAmount);
		
		// 借款金额，即本金
		BigDecimal borroweAmount = projectBorrowerAmountSumDTO.getBorrowedAmount();
		
		// 构建请求数据
		ProjectRefundEventRequest projectRefundEventRequest = new ProjectRefundEventRequest();
		projectRefundEventRequest.setUserId(project.getBorrowUserId());
		projectRefundEventRequest.setProjectId(project.getProjectId());
		projectRefundEventRequest.setBorrowedAmount(borroweAmount);
		projectRefundEventRequest.setDoneAmount(doneAmount);
		projectRefundEventRequest.setLateAmount(lateAmount);	
		projectRefundEventRequest.setUpdateTime(new Date().getTime() * 1000L);
		projectRefundEventRequest.setProjecterPayment(projectRefundEventRequestDetailList);

		return projectRefundEventRequest;
	}

	@Override
	public RefundNotifyEnum getType() {
		return RefundNotifyEnum.TIANCHENG_BORROWER_REFUND;
	}	
}